#ifndef XXX_TYPES_H
#define XXX_TYPES_H

#include <ext2fs/ext2fs.h>
#include <stdbool.h>
#define XXX_MAGIC_NUM 0xAAAA


/* xxx_file is a invisible file created by xxx-ext4 which located at a ext4(ext3) file system.
 * Its inode number is reserved EXT2_UNDEL_DIR_INO (6).
 * It contains all the information handled by this xxx-ext4 software.
 * There is no path or name for this file, so you cannot access it by standard IO operations.
 *
 * xxx_file's content startswith xxx_super_area, the meta info about this file.
 * xxx_super_area defines the following data in xxx_file.
 * xxx_journal_item stores some log.
 * xxx_mapping_item keeps the relation between a hidden(encrypted) file and a shown(visiable) file.
 * journal_area : a list of xxx_journal_items.
 * mapping_area : a list of xxx_mapping_items.

 * When hiding a file, we unlink (filesystem level) it to the directory and encrypt the content of its inode.
 * When showing a file, we decrypt the content of its inode and link (filesystem level) it to the directory.
 * xxx_mapping_item keeps the relation between a hidden(encrypted) file and a shown(visiable) file.
 *
 * Functions use xxx_info struct to get filesystem information and record operations.
 * The buffer in xxx_info is the content of xxx_file.
 * xxx_super_area, journal_items and mapping_items are pointed to different positions of the buffer.
 *
 * Load xxx_info from the path, which is the first step to use xxx lib.
 * It will do these things:
 *   1. init mount table using libmount.so
 *   2. find the mount point and device path of given path
 *   3. pass the mount point and device path to struct xxx_info
 *   4. try to open fs and read xxx_info if it exists
 */

struct xxx_super_area
{
    __u16 magic_number;
    __u32 xxx_info_length;

    __u8 version;
    __u8 is_removable_dev;
    __u8 is_using_passwd;
    __u8 encrypt_algorithm;

    __u32 journal_area_offset;
    __u32 journal_area_length;
    __u16 journal_item_count;

    __u32 mapping_area_offset;
    __u32 mapping_area_length;
    __u16 mapping_item_count;

    char local_dev_path[64];
    char description[256];
};

struct xxx_mapping_item
{
    __u8 is_used;
    __u8 encrypt_algorithm;
    ext2_ino_t shown_ino_t;
    struct hidden_entry {
        ext2_ino_t hidden_ino_t;
        char name[255];
        __u8 filetype;
    } hidden_entry;
};

struct xxx_journal_item
{
    time_t timestamp;
    char message[64];
};

struct xxx_info
{
    void *buff;
    __u32 buff_length;
    struct xxx_super_area *super_area;      // related to the buff
    struct xxx_journal_item *journal_items; // related to the buff
    struct xxx_mapping_item *mapping_items; // related to the buff
    __u16 journal_item_count;
    __u16 mapping_item_count;

    ext2_filsys fs;
    struct libmnt_table *table;
    const char *devpath;    // related to the table
    const char *mountpoint; // related to the table

    // TODO : dirty bits
};


extern const struct xxx_super_area default_xxx_super_area;


#endif
